<!DOCTYPE html>
<html>
	<head>
		<meta charset="utf-8">
		<title></title>
		<style>
			table{
				width: 400px;
				border-collapse: collapse;
			}
			th{
				border:1px solid lightgray;
			}
			td{
				border:1px solid lightgray;
				text-align: center;
			}
			.currentMonth{
				background-color:lightblue;
			}
			.otherMonth {
				background-color: lightcyan;
			}
			.currentDate{
				background-color:darkblue;
				color:red;
			}
			#title th{
				cursor: pointer;
			}
			#calendarBody td{
				cursor:pointer
			}
			#calendarBody td:hover{
				background-color:deepskyblue;
			}
		</style>
	</head>
	<body>
		<input type="text" id="txtSelectedDate" />
		
		<table id="title" cellpadding="5px" cellspacing="0">
			<tr>
				<th id="prevYear">&lt;&lt;</th>
				<th id="prevMonth">&lt;</th>
				<th><span id="spnYear"></span>年</th>
				<th><span id="spnMonth"></span>月</th>
				<th id="nextMonth">&gt;</th>
				<th id="nextYear">&gt;&gt;</th>
			</tr>
		</table>
		<table id="calendar" cellpadding="5px" cellspacing="0">
			<thead>
				<tr>
					<th>周一</th>
					<th>周二</th>
					<th>周三</th>
					<th>周四</th>
					<th>周五</th>
					<th>周六</th>
					<th>周日</th>
				</tr>
			</thead>
			<tbody id="calendarBody">
				
			</tbody>
		</table>
		<script>
			var TotalDays = 42;			// 日历显示6行，每行7列，共42个单元格(42个日期)
			var dateArray = new Array(TotalDays);	// 存放填在42个单元格中的年月日数据
			var filledDays = 0;			// 目前为止已经填充的单元数
			
			// 判断是否为闰年
			function isLeapYear(year){
				return ((year % 100 != 0) && (year % 4 == 0)) || (year % 400 == 0);
			}
			
			// 返回各月的天数
			function getMonthDays(year, month){
				switch(month){
					case 4:
					case 6:
					case 9:
					case 11:
						return 30;
					case 2:
						return isLeapYear(year) ? 29 : 28;
					default:
						return 31;
				}
			}
			
			// 填充本月之前月末若干天的单元格			
			function generatePrevMonthDays(year, month){
				var monthFirstDate = new Date(year, month - 1, 1);
				var monthFirstDay = monthFirstDate.getDay();
				monthFirstDay = (monthFirstDay == 0) ? 7 : monthFirstDay;
				if(monthFirstDay == 1){
					return;
				}
				var lastYear = (month == 1 ? year-1 : year);
				var lastMonth = (lastYear == year) ? (month-1) : 12;
				var lastDate = getMonthDays(lastYear, lastMonth) - monthFirstDay + 2;
				
				for(var i=0; i<monthFirstDay - 1; i++){
					dateArray[filledDays] = {year:lastYear, month:lastMonth, date:lastDate+i};
					filledDays++;
				}
			}
			
			// 填充本月单元格
			function generateCurrentMonthDays(year, month){
				var monthFirstDate = new Date(year, month-1, 1);
				var monthDays = getMonthDays(year, month);
				var monthLastDate = new Date(year, month-1, monthDays);
				var monthFirstDay = monthFirstDate.getDay();
				monthFirstDay = (monthFirstDay == 0) ? 7 : monthFirstDay;
				
				for(var i=0;i<monthDays;i++){
					dateArray[filledDays] = {year:year, month:month, date:i + 1};
					filledDays++;
				}
			}
			
			// 填充本月之后月前若干天的单元格
			function generateNextMonthDays(year, month){
				var nextYear = (month == 12) ? (year + 1) : year;
				var nextMonth = (month == 12) ?  1 : (month + 1);
				var leftDays = TotalDays - filledDays;
				for(var i=0;i<leftDays;i++){
					dateArray[filledDays] = {year: nextYear, month:nextMonth, date: i + 1};
					filledDays++;
				}
			}
			
			// 填充单元格，并且根据单元格中的日期数据生成Calendar HTML表格
			function generateCalendarHtml(year, month){
				filledDays = 0;
				generatePrevMonthDays(year, month);
				generateCurrentMonthDays(year, month);
				generateNextMonthDays(year, month);
				
				document.getElementById("spnYear").innerHTML = 	year;
				document.getElementById("spnMonth").innerHTML = month;
				
				var calendarBody = document.getElementById("calendarBody");
				var txtSelectedDate = document.getElementById("txtSelectedDate");
				calendarBody.innerHTML = "";
				var rows = TotalDays / 7;
				for(var i=0;i<rows;i++){
					var tr = document.createElement("tr");
					for(var j=0;j<7;j++){
						var td = document.createElement("td");
						var index = i*7 + j;
						
						td.dataset.dateIndex = index;
						td.innerHTML = dateArray[index].date;
						
						if(dateArray[index].month == month){
							if(dateArray[index].date == day){
								td.classList.add("currentDate");								
							} else{
								td.classList.add("currentMonth");
							}
						} else{
							td.classList.add("otherMonth");
						}
						
						td.onclick = function(){
							var dateObj = dateArray[this.dataset.dateIndex]
							txtSelectedDate.value = dateObj.year + "-" + dateObj.month + "-" + dateObj.date;	
						}

						tr.appendChild(td);
					}
					calendarBody.appendChild(tr);
				}
			}
			
			function initCalendarHeader(year, month){
				document.getElementById("prevYear").onclick = function(){
					year = year - 1;
					generateCalendarHtml(year, month);
				};
				document.getElementById("prevMonth").onclick = function(){
					year = (month == 1) ? (year - 1) : year;
					month = (month == 1) ? 12 : month - 1;
					generateCalendarHtml(year, month);
				};
				document.getElementById("nextMonth").onclick = function(){
					year = (month == 12) ? (year + 1) : year;
					month = (month == 12) ? 1 : month + 1;
					generateCalendarHtml(year, month);
				};
				document.getElementById("nextYear").onclick = function(){
					year = year + 1;
					generateCalendarHtml(year, month);
				};
			}
			
			var year = 2015, month = 11, day = 28;
			initCalendarHeader(year, month);
			generateCalendarHtml(year, month);
		</script>
	</body>
</html>
